/**
 * Created by yanwc on 15-5-29.
 */
(function(){

    //定义画布环境变量及场景
    var canvas = null;
    var stage = null ;
    var scene = null;

    //定义绘制直线的线段
    var beginNode = null;
    var tempNodeA =  null;//
    var tempNodeZ =null;
    var link = null;
    var rightMenuOperObj = null;

    var operState = {
        state_default:"default",
        state_fullscreen:"fullscreen",
        state_center:"center",
        state_magnifier:"magnifier",
        state_shrink:"shrink",
        state_recover:"recover",
        state_line:"line",
        state_foldline:"foldline",
        state_eagleye:"eagleye"
    };

    var state = operState.state_default;

    var height,width;//定义容器的高度和宽度

    //开始绘制直线，并初始化线段
    var  beginDrawLine = function(action) {
        tempNodeA = new JTopo.Node('tempA');
        tempNodeA.setSize(1, 1);
        tempNodeZ = new JTopo.Node('tempZ');
        tempNodeZ.setSize(1, 1);
        link = createLink(tempNodeA,tempNodeZ,action);//

    }

    var  clearDrawLineState = function(){
        tempNodeA = null;
        tempNodeZ = null;
        beginNode = null;
        scene.remove(link);
        line = null;

    }

    var scene_dbclick = function(event){
        if(event.target instanceof JTopo.Link){
            scene.remove(event.target);
        }
    }

    //创建工具条
    var createToolBar = function(target){

        var css ;
        var background_image ;
        var background_size;
        var isSelected = false;

        var $toolbar = $("<div class='detail_r'/>");
        //var $tool = $("<div class='tool'/>");
        var $container = $("<div class='tool_bar'/>");
        //$tool.append($container);
        $container.append($("<span value='default'/>").addClass("default").attr("title","默认"));
        //$container.append($("<span value='fullscreen'/>").addClass("fullscreen").attr("title","全屏"));
        //$container.append($("<span value='center'/>").addClass("center").attr("title","居中"));
        //$container.append($("<span value='magnifier'/>").addClass("magnifier").attr("title","放大"));
       // $container.append($("<span value='shrink'/>").addClass("shrink").attr("title","缩小"));
        //$container.append($("<span value='recover'/>").addClass("recover").attr("title","恢复"));
        $container.append($("<span value='line'/>").addClass("line").attr("title","连线"));
        $container.append($("<span value='foldline'/>").addClass("foldline").attr("title","L形连线"));
        //$container.append($("<span value='eagleye'/>").addClass("eagleye").attr("title","鹰眼"));

        var $select = $("<select/>");
        $container.append($select.append("<option value='circlelayout'>圆形布局</option>"));
        $container.append($select.append("<option value='treelayout'>树形布局</option>"));
        $toolbar.append($container);
            if( target){
            target.append($toolbar);
        }
         $toolbar.append("<input type='button' value='保存' class='save' id='save_tuopu' onclick='saveTopoData()'/>");
        //
        $(target).find("select").change(function(event){
            //JTopo.layout.layoutNode(scene, cloudNode, true);
            var value = $(event.target).attr("value");
            var layout = null;
            switch(value){
                case "circlelayout":
                    layout = {type: 'circle', radius: 150};
                    break;
                case "treelayout":
                    layout = {type: 'tree', width:50, height: 100};
                    break;
            }
            if(layout != null){
                scene.childs.forEach(function(element){
                   if(element instanceof JTopo.Node) {
                       element.layout= layout;
                   }
                });
                JTopo.layout.layoutNode(scene, scene.getDisplayedNodes()[0], true);
            }
        });


        var css ;
        var background_image ;
        var background_size;
        var isSelected = false;

        $(".tool_bar span").mouseover(function(){
            background_image = $(this).css("background-image");
            background_size = $(this).css("background-size");
            css = $(this).attr("class");
            $(this).attr("class","over");
            $(this).css("background-image",background_image);
            $(this).css("background-size",background_size);
        }).mouseout(function(){
            $(this).removeClass('over');
            $(this).addClass(css);
            $(this).css("background-image",background_image);
            $(this).css("background-size",background_size);
        });

        $(".tool_bar span").click(function(){
            $(this).siblings().removeClass('selected');
            $(this).addClass("selected");

            var action = $(this).attr("value");
            state = action;
            switch(action) {
                case operState.state_default:
                    clearDrawLineState();
                    break;
                case operState.state_center:
                    break;
                case operState.state_shrink:
                    break;
                case operState.state_recover:
                    break;
                case operState.state_line:
                    beginDrawLine(action);
                    break;
                case operState.state_foldline:
                    beginDrawLine(action);
                    break;
                case operState.state_eagleye:
                    break;
                case operState.state_magnifier:
                    break;
            }

        });
        return $toolbar;
    }

    //创建节点资源菜单
    var createNodelist = function(target,opt){
        if(!opt || !opt.list){
            target.append("<h1>无可用数据</h1>");
            return;
        }
        var $nodeList = $("<div class='nodeList'/>");
        var $title = $("<div class='listName'/>");

        $title.text(opt.title);
        $nodeList.append($title);
        opt.list.forEach(function(obj){
            $detail02 =$("<div class='detail02'/>");

            $detail_title = $("<div class='detail_title'/>");
            $detail02.append($detail_title);

            $p_span=$("<p>"+obj.typename+"</p><span></span>");
            $detail_title.append($p_span);

            $get_detail = $("<div id='"+obj.typeid+"' class='get_detail'/>");
            $detail02.append($get_detail);

            if(obj.nodes){
                obj.nodes.forEach(function(node){
                    var $img = $("<img  draggable='true' style='height:16px;width:16px;'  src='"+node.imgUrl+"' class='node' title='"+node.caption+"' id='"+node.id+"' caption='"+node.caption+"' data='"+node.data+"'></img>");
                    //添加拖拽事件
                    $img[0].ondragstart = function(ev) {
                        var dt = ev.dataTransfer;
                        dt.setData("id", $(this).attr("id"));
                        var id = dt.getData("id");
                        dt.setData("typeid", $(this).parent().attr("id"));

                        return true;
                    }
                    $get_detail.append($img);
                });
            }

            $nodeList.append($detail02);
        });
        target.append($nodeList);

        //设置点击操作
        $(".detail_title span").addClass("down");
        $(".detail_title span").click(function(){

            if($(this).parent().siblings().css('display')=='block'){
                $(this).parent().siblings().hide(300);
                $(this).removeClass("down");
                $(this).addClass("up");
            }else{
                $(this).parent().siblings().show(300);
                $(this).removeClass("up");
                $(this).addClass("down");
            };
        });

      //鼠标经过效果
		$('.get_detail .node').hover(function(e) {
			$(this).css('background','#d5d5d5')
		},function(){
			$(this).css('background','#fff')
		});

        return $nodeList;
    }

    //添加右键菜单
    var createRihtMenu = function(target){
        var $ul = $("<ul class='contextmenu' style='display:none;'>");
        $ul.append("<li><a value='delete'>删除</a></li>");
        target.append($ul);
        target.find(".contextmenu li a").click(function(event){
            //删除节点或连线
            if($(this).attr("value") == "delete"){
                if(rightMenuOperObj != null ){
                    if(rightMenuOperObj instanceof  JTopo.Link){
                        scene.remove(rightMenuOperObj);
                    }else if(rightMenuOperObj instanceof  JTopo.Node){
                        addNodetoNodeList(rightMenuOperObj);
                        //删除节点需删除与该节点所有的连线
                        var outLinks = rightMenuOperObj.outLinks;
                        var inLinks = rightMenuOperObj.inLinks;
                        if(outLinks){
                            outLinks.forEach(function(link){
                                scene.remove(link);
                            });
                        }
                        if(inLinks){
                            inLinks.forEach(function(link){
                                scene.remove(link);
                            })
                        }
                        scene.remove(rightMenuOperObj);
                    }
                }
            }
            $(this).parent().parent().hide();
        }).mouseout(function(){
			$(this).parent().parent().hide();
		});

    }
    //创建拓扑组件
    var createJtopo = function(target,width,height){
        var $canvas = $("<canvas width='"+width+"px' height='"+height+"px' ondrop='dragDrop(event)'></canvas>");
        target.append($canvas);
        $canvas[0].ondrop = function(ev){
            var dt = ev.dataTransfer;
            var id = dt.getData("id");
            addNode(id,ev,true);
            ev.preventDefault();
        }

        $canvas[0].ondragover = function(ev){
            ev.preventDefault();
            return true;
        };
        return target;
    }


    //开始绘制折线
    function beginDrawBrokenLine(){
        //TODO 设置折现初始化
    }

    /**
     *
     * @param node 被拖拽的节点的ｉｄ
     * @param event drop事件
     * @param isClearOriginNode 是否删除被拖拽节点
     */
    var addNode = function (node,event,isClearOriginNode){
        var $node = $("#"+node);
        var imgUrl = $node.attr("src");
        var id = $node.attr("id");
        var caption=$node.attr("caption");
        var data = $node.attr("data");
        var typeid= event.dataTransfer.getData("typeid");
		
		var img = new Image();
		img.src = imgUrl;
		if(img.complete){
			ImgHeight=img.height/2+8;
		};
        //var box = (event.target || event.srcElement).getBoundingClientRect();
        //console.info("--------------->"+$("#topoCanvas").position().left);
        //获得对象相对于页面的横坐标值；id为对象的id
        var thisX =canvas.offsetLeft;
        //获得对象相对于页面的横坐标值；
        var thisY =canvas.offsetTop;
        //获得页面滚动的距离；
        //注：document.documentElement.scrollTop为支持非谷歌内核；document.body.scrollTop为谷歌内核
        var thisScrollTop = document.documentElement.scrollTop + document.body.scrollTop;
        event = event||window.event;
        //获得相对于对象定位的横标值 = 鼠标当前相对页面的横坐标值 - 对象横坐标值；
        var x = event.clientX - thisX;
        //获得相对于对象定位的纵标值 = 鼠标当前相对页面的纵坐标值 - 对象纵坐标值 + 滚动条滚动的高度；
        var y = event.clientY - thisY + thisScrollTop;

        //scene.background = './img/bg.jpg';
		
        var newNode = new JTopo.Node();
        newNode.id=id;
        newNode.imgUrl =imgUrl;
        newNode.data = data;
        newNode.text = caption; // 文字
        newNode.typeid= typeid;
        newNode.textPosition = 'Middle_Center';// 文字居中
        newNode.textOffsetY = ImgHeight; // 文字向下偏移8个像素
        newNode.font = '10px'; // 字体
        newNode.setLocation(x,y)// 位置
        newNode.fontColor="0,0,0"
        //newNode.setSize(32,32);  // 尺寸
        newNode.borderRadius = 5; // 圆角
        newNode.borderWidth = 2; // 边框的宽度
        newNode.borderColor = '255,255,255'; //边框颜色
        newNode.alpha = 1; //透明度
        newNode.setImage(imgUrl,true);
        scene.add(newNode);

        if(isClearOriginNode){
            $(".nodeList .node").remove("#"+node);
        }

    };
	
	
    var addNodetoNodeList = function(obj){
        var $htmlString = $("<img src=\""+obj.imgUrl+"\" style=\"width:16px;height:16px\" class=\"node\" draggable=\"true\" ondragstart=\"onDragstart(event);\"  id=\""+ obj.id + "\" caption=\""+obj.text+"\" data=\""+obj.data+"\"/>");
        $("#"+obj.typeid).append( $htmlString);
        $htmlString[0].ondragstart =  function (ev){
            var dt = ev.dataTransfer;
            var target = ev.target;
            dt.setData("id",$(target).attr("id"));
            dt.setData("typeid",$(target).parent().attr("id"));
            var id = dt.getData("id");
            return true;
        }
    };

    //插件默认传递参数
    var defaultNodeList={
        data:{title:"资源列表",list:[{typeid:"type1",typename:"网路设备",nodes:[{id:"node1",caption:"caption1",imgUrl:"img/detail__05.png"},
            {id:"node2",caption:"caption2",imgUrl:"img/detail__06.png"}]},
            {typeid:"type2",typename:"主机设备",nodes:[{id:"host_node3",caption:"caption2",imgUrl:"img/detail__06.png"},
                {id:"node1",caption:"caption1",imgUrl:"img/detail__05.png"}]}
        ]}
    };

    var topoData ={
        types:[
            {typeid:"",nodes:[{id:"",caption:"",imgUrl:"",x:"",y:""},{id:"",caption:"",imgUrl:"",x:"",y:""}]},
            {typeid:"",nodes:[{id:"",caption:"",imgUrl:"",x:"",y:""},{id:"",caption:"",imgUrl:"",x:"",y:""}]}
        ],
        links:[{fromid:"",toid:"",isFoldLine:false},{fromid:"",toid:"",isFoldLine:false},{fromid:"",toid:"",isFoldLine:false}]
    }


    var initTopo = function(topoData){
        if(topoData){
            if(topoData.types){
                topoData.types.forEach(function(type){
                    if(type.nodes){
                        type.nodes.forEach(function(n){
                            var node = new JTopo.Node;
                            node.id = n.id;
                            node.setImage(n.imgUrl,true);
                            node.text = n.caption;
                            node.typeid = type.typeid;
                            node.imgUrl = n.imgUrl;
                            node.x = n.x;
                            node.y = n.y;

                            node.font = '10px'; // 字体

                            node.fontColor="0,0,0"
                           // node.setSize(3,64);  // 尺寸
                            node.borderRadius = 5; // 圆角
                            node.borderWidth = 2; // 边框的宽度
                            node.borderColor = '255,255,255'; //边框颜色
                            node.alpha = 1; //透明度
                            scene.add(node);
                        });
                    }
                });
            }

            if(topoData.links){
                topoData.links.forEach(function(l){
                    //循环节点，查找与线对应的节点然后创建连线
                    var nodeA = null;
                    var nodeZ = null;
                    var link = null;

                    scene.childs.forEach(function(element){
                        if(element instanceof JTopo.Node){
                            if(l.fromid == element.id){
                                nodeA = element;
                            }else if(l.toid == element.id){
                                nodeZ = element;
                            }
                        }
                    })
                    if(nodeA != null && nodeZ != null){
                        if(l.isFoldLine){
                            link = new JTopo.FoldLink(nodeA,nodeZ);
                        }else{
                            link = new JTopo.Link(nodeA,nodeZ);
                        }
                        scene.add(link);
                    }
                });
            }
        }
    }

    var createLink = function(nodeA,nodeB,state){
        var link = null;
        if(state == operState.state_line){
            link = new JTopo.Link(nodeA,nodeB);
        }else if(state == operState.state_foldline){
            link = new JTopo.FoldLink(nodeA,nodeB);
        }else{
            console.info("Can't create line! ");
        }
        return link;
    }


    //声明插件，调用入口
    $.fn.topoEdit=function(nodelist,topoData){
        $.extend({},defaultNodeList,nodelist);
        var $target = $(this);
        var height = $(this).height();
        //创建资源列表
        var $nodeList = createNodelist($(this),nodelist);
        var $toolBar = createToolBar($(this));
        var width = $(this).width()-$nodeList.width();
        $toolBar.width(width-40);
        createJtopo($toolBar,width,height);
        createRihtMenu($(this));
        canvas =$(this).find("canvas")[0];
        stage = new JTopo.Stage(canvas);
        scene  = new JTopo.Scene(stage);
        //初始化节点数据
        initTopo(topoData);

        scene.mouseup(function(e){
            if( state != operState.state_line && state != operState.state_foldline)return null;
            if(e.button == 2){
                scene.remove(link);
                return;
            }
            if(e.target != null && e.target instanceof JTopo.Node){
                if(beginNode == null){
                    beginNode = e.target;
                    scene.add(link);
                    tempNodeA.setLocation(e.x, e.y);
                    tempNodeZ.setLocation(e.x, e.y);
                }else if(beginNode !== e.target){
                    var endNode = e.target;

                    var l =createLink(beginNode,endNode,state);// new JTopo.Link(beginNode, endNode);
                    scene.add(l);
                    beginNode = null;
                    scene.remove(link);
                }else{
                    beginNode = null;
                }
            }else{
                scene.remove(link);
                beginNode = null;
            }
        });

        scene.mousedown(function(e){
            if(e.button == 2 && ( e.target instanceof JTopo.Link || e.target instanceof JTopo.Node) ){
                rightMenuOperObj = e.target;
                //右键显示菜单
                $target.find(".contextmenu").css({
                    top: e.pageY,
                    left: e.pageX
                }).show();

            }
            if( state != operState.state_line && state != operState.state_foldline)return null;
            if(e.target == null || e.target === beginNode || e.target === link){

                scene.remove(link);
                beginNode = null;
            }else{

            }
        });

        scene.mousemove(function(e){
            if( state != operState.state_line && state != operState.state_foldline)return null;
            tempNodeZ.setLocation(e.x, e.y);

        });


        return {
            getTopoData:function(){
                var topoData ={};
                topoData.types=[];
                topoData.links=[];
                scene.childs.forEach(function(element) {

                    if(element instanceof JTopo.FoldLink) {
                        var link = {};
                        link.fromid = element.nodeA.id;
                        link.toid = element.nodeZ.id;
                        link.isFoldLine = true;
                        topoData.links.push(link);
                    }else if(element instanceof JTopo.Link){
                       var link ={};
                        link.fromid = element.nodeA.id;
                        link.toid = element.nodeZ.id;
                        link.isFoldLine = false;
                        topoData.links.push(link);
                    }else if(element instanceof  JTopo.Node){
                        var node={};
                        node.imgUrl=element.imgUrl;
                        node.id = element.id;
                        node.caption = element.text;
                        node.data = element.data;
                        node.x = element.x;
                        node.y = element.y;
                        var isAdd = false;

                        topoData.types.forEach(function(obj){
                            if(obj.typeid == element.typeid){
                                if(obj.nodes){
                                    isAdd = true;
                                    obj.nodes.push(node);
                                }

                            }
                        });

                        if(!isAdd) {
                            var type = {};
                            type.typeid = element.typeid;
                            type.nodes = [];
                            type.nodes.push(node);
                            topoData.types.push(type);
                        }
                    }

                });
                return JSON.stringify(topoData);
            }
        };
    }

})();
